package com.webservice.impl.allot;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.webservice.dao.IAllotInBillBackDao;
import com.webservice.dao.Pub;
import com.webservice.dao.PubBaseDao;
import com.webservice.impl.Customer;
import com.webservice.service.IBaseService;
import com.webservice.utils.DateTimeTool;
import com.webservice.utils.UUIDUtil;
import com.webservice.utils.VOXMLMapping;
import com.webservice.vo.AllotInBillDetailInfo;
import com.webservice.vo.AllotInBillImeiInfo;
import com.webservice.vo.AllotOutBillFromXml;
import com.webservice.vo.Product;
import com.webservice.vo.Seri;

/**
 * @ClassName: AllotInBillBack
 * @Description:
 * @author gaobing03@chinatelling.com
 * @date 2013-12-23 上午11:26:01
 * 
 */
@Service("B1003")
public class AllotInBillBackService implements IBaseService {
	private static Logger logger = Logger.getLogger(Customer.class);

	@Autowired
	@Qualifier("AllotInBillBackDao")
	private IAllotInBillBackDao allotInBillBackDao;

	@Override
	public String returnData(String xml, PubBaseDao baseDao, String ip) throws Exception {
		String allotcode = "";
		String intocode = "";
		String returnxml = "";
		String intoUUID = UUIDUtil.getUUID();
		String outUUID = UUIDUtil.getUUID();
		// 成对标志
		String pairflag = DateTimeTool.getDateTimeString(new Date(),"yyyymmddHHmmss:sss").replace(":", "");
		try {
			return dealBusiness(xml,baseDao,ip);
		} catch (Exception e) {
			e.printStackTrace();
			try {
				returnxml=returnXml(allotcode,intocode,"-1","报文解析失败");
				Pub.insertLog(baseDao, intoUUID, ip, "13", "", xml, "into",pairflag,"0");//调拨入库
				Pub.insertLog(baseDao, outUUID, ip, "13", intocode, returnxml, "out",pairflag,"1");//调拨入库
				Pub.insertDealResultLog(baseDao, outUUID, "WMS", "B2B", "处理异常", e.toString());
			} catch (Exception et) {
				et.printStackTrace();
				throw new Exception(returnxml);
			}
			throw new Exception(returnxml);
		}
	}
	
	@Transactional(value = "txManager", isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = { Exception.class })
	private String dealBusiness(String xml, PubBaseDao baseDao, String ip) throws Exception{
		String allotcode = "";
		String intocode = "";
		String returnxml = "";
		String intoUUID = UUIDUtil.getUUID();
		String outUUID = UUIDUtil.getUUID();
		// 成对标志
		String pairflag = DateTimeTool.getDateTimeString(new Date(),"yyyymmddHHmmss:sss").replace(":", "");
		try {
			AllotOutBillFromXml allotOutBill = (AllotOutBillFromXml) VOXMLMapping
					.fromXML(xml, AllotOutBillFromXml.class, null);// 反射xml-->实体类
			Pub.insertLog(baseDao, intoUUID, ip, "13", allotOutBill.getIntocode(), xml, "into",pairflag,"0");// 调拨入库
			
			String validateResult = this.validateXml(allotOutBill);
			if (!"".equals(validateResult)) {
				allotcode = allotOutBill.getAllotcode();
				intocode = allotOutBill.getIntocode();
				returnxml = returnXml(allotcode, intocode, "-1", validateResult);
				Pub.insertLog(baseDao, outUUID, ip, "13", allotOutBill.getIntocode(), returnxml, "out",pairflag,"1");// 调拨入库
				Pub.insertDealResultLog(baseDao, outUUID, "WMS", "B2B", "处理异常", validateResult);
				return returnxml;
			} else {
				allotcode = allotOutBill.getAllotcode();
				intocode = allotOutBill.getIntocode();
				String state=allotInBillBackDao.getIntoStoreState(intocode);
				if("3".equals(state)||"4".equals(state)){
					returnxml = returnXml(allotcode, intocode, "-1", "该入库单已入库，不能重复入库");
					Pub.insertLog(baseDao, outUUID, ip, "13", allotOutBill.getIntocode(), returnxml, "out",pairflag,"1");// 调拨入库
					Pub.insertDealResultLog(baseDao, outUUID, "WMS", "B2B", "处理异常", "该入库单已入库，不能重复入库");
					return returnxml;
				}
				List<Product> plist = allotOutBill.getProducts();
				List<Product> eplist = allotOutBill.getErrorproducts();
				List<AllotInBillDetailInfo> details = new ArrayList<AllotInBillDetailInfo>();
				List<AllotInBillImeiInfo> imeiInfos = new ArrayList<AllotInBillImeiInfo>();
				boolean flag = true;
				if (plist != null) {
					for (Product p : plist) {
						int quantity = allotInBillBackDao.getQuantity(
								allotOutBill.getAllotcode(), p.getProductcode()
										+ "", p.getSupplyid() + "");
						if (!StringUtils.equals(quantity + "", p.getQuantity()
								+ "")) {// 实际入库数量和应入库数量不一致时，更新入库表状态为部分入库
							flag = false;
						}
						AllotInBillDetailInfo detail = new AllotInBillDetailInfo();
						detail.setActualnum(p.getQuantity());// 实际入库数量
						detail.setBillcode(allotOutBill.getIntocode());// 入库单号
						detail.setDr(0);
						String pk_intobilldetail = UUIDUtil.getUUID();
						detail.setPk_intodetail(pk_intobilldetail);// 入库明细主键
						detail.setProducid(p.getProductcode());// 产品号
						detail.setQuantity(quantity);// 应入库数
						detail.setSupplyid(p.getSupplyid());// 供应商id
						detail.setTs(DateTimeTool.getDateTimeString(new Date()));// 入库时间
						detail.setType("1");
						details.add(detail);
						List<Seri> slist = p.getSerials();
						if (slist != null) {
							for (Seri s : slist) {// 获得产品的imei号
								AllotInBillImeiInfo imei = new AllotInBillImeiInfo();
								imei.setDr(0);
								imei.setImei(s.getImei());
								imei.setPk_intobilldetail(pk_intobilldetail);
								imei.setPk_intoimei(UUIDUtil.getUUID());
								imei.setTs(DateTimeTool
										.getDateTimeString(new Date()));
								imei.setImeitype("1");// 成功
								imeiInfos.add(imei);
							}
						}
					}
				}
				if (eplist != null) {
					for (Product p : eplist) {
						int quantity = allotInBillBackDao.getQuantity(
								allotOutBill.getAllotcode(), p.getProductcode()
										+ "", p.getSupplyid() + "");
//						if (!StringUtils.equals(quantity + "", p.getQuantity()
//								+ "")) {// 实际入库数量和应入库数量不一致时，更新入库表状态为部分入库
//							flag = false;
//						}
						AllotInBillDetailInfo detail = new AllotInBillDetailInfo();
						detail.setActualnum(p.getQuantity());// 实际入库数量
						detail.setBillcode(allotOutBill.getIntocode());// 入库单号
						detail.setDr(0);
						String pk_intobilldetail = UUIDUtil.getUUID();
						detail.setPk_intodetail(pk_intobilldetail);// 入库明细主键
						detail.setProducid(p.getProductcode());// 产品号
						detail.setQuantity(quantity);// 应入库数
						detail.setSupplyid(p.getSupplyid());// 供应商id
						detail.setTs(DateTimeTool.getDateTimeString(new Date()));// 入库时间
						detail.setType("0");
						details.add(detail);
						List<Seri> slist = p.getSerials();
						if (slist != null) {
							for (Seri s : slist) {// 获得产品的imei号
								AllotInBillImeiInfo imei = new AllotInBillImeiInfo();
								imei.setDr(0);
								imei.setImei(s.getImei());
								imei.setPk_intobilldetail(pk_intobilldetail);
								imei.setPk_intoimei(UUIDUtil.getUUID());
								imei.setTs(DateTimeTool
										.getDateTimeString(new Date()));
								imei.setImeitype("0");// 失败
								imeiInfos.add(imei);
							}
						}
					}
				}
				// 1,更新入库单状态
				if (flag) {
					this.allotInBillBackDao.updateInBill(
							allotOutBill.getIntocode(), "4");// 全部入库
				} else {
					this.allotInBillBackDao.updateInBill(
							allotOutBill.getIntocode(), "3");// 部分入库
				}
				// 2,往入库明细表插入出库明细
				this.allotInBillBackDao.batchInsertInBillDetail(details);
				// 3，往入库串号表插入串号信息
				this.allotInBillBackDao.batchInsertInBillImei(imeiInfos);
				// 4，更新调拨单状态为调拨完成
				this.allotInBillBackDao.updateAllotBill(allotcode);
				this.allotInBillBackDao.updateAllotPlanStatus("3",allotcode);
				// 5, 更新库存 出库在途去数，入库可有数增加
				List<String[]> store = this.allotInBillBackDao
						.getPkStore(allotcode);
				if (store != null && store.size() > 0) {
					String[] pk = store.get(0);
					this.allotInBillBackDao.updateFromStoreNum(pk[0], details);
					this.allotInBillBackDao.updateToStoreNum(pk[1], details);
					this.allotInBillBackDao.batchUpdateSupplyArea0(pk[1], details);//更新非定向发布数
				}
			}
			returnxml = returnXml(allotcode, intocode, "0", "成功");
			Pub.insertLog(baseDao, outUUID, ip, "13", allotOutBill.getIntocode(), returnxml, "out",pairflag,"1");// 调拨入库
			Pub.insertDealResultLog(baseDao, outUUID, "WMS", "B2B", "成功", "调拨入库回传处理成功");
			return returnxml;
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.getMessage());
		}
	}
	
	private String returnXml(String allotcode, String outcode, String flag,
			String text) {
		String returnXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><returnmsg><allotcode>"
				+ allotcode
				+ "</allotcode><intocode>"
				+ outcode
				+ "</intocode>"
				+ "<result>"
				+ flag
				+ "</result><msg>"
				+ text
				+ "</msg></returnmsg>";
		System.out.println(returnXml);
		return returnXml;
	}

	public String validateXml(AllotOutBillFromXml allotOutBill)
			throws Exception {
		String validateResult = "";
		if (StringUtils.isBlank(allotOutBill.getAllotcode())) {
			validateResult = "调拨单号不能为空";
			return validateResult;
		}
		if (StringUtils.isBlank(allotOutBill.getIntocode())) {
			validateResult = "入库单号不能为空";
			return validateResult;
		}
		List<Product> products = allotOutBill.getProducts();
		if (products == null || products.size() < 0) {
			// validateResult = "product不能为空！";
			return validateResult;
		} else {
			for (Product product : products) {
				if (StringUtils.isBlank(product.getProductcode() + "")) {
					validateResult = "产品编码不能为空";
					return validateResult;
				}
				if (StringUtils.isBlank(product.getQuantity() + "")) {
					validateResult = "产品数量不能为空";
					return validateResult;
				}
				if (product.getSupplyid() < 0) {
					validateResult = "供应商不能为空";
					return validateResult;
				}
				List<Seri> seris = product.getSerials();
				if ((seris != null) && seris.size() != product.getQuantity()) {
					if (product.getQuantity() != 0)
						validateResult = "quantity数量和imei个数不相等";
					else
						validateResult = "";
					return validateResult;
				} 
			}
		}
		List<Product> errorproducts = allotOutBill.getErrorproducts();
		if (errorproducts == null || errorproducts.size() == 0) {
			// validateResult="errorproduct不能为空！";
		} else {
			for (Product product : errorproducts) {
				if (StringUtils.isBlank(product.getProductcode() + "")) {
					validateResult = "产品编码不能为空";
					return validateResult;
				}
				if (StringUtils.isBlank(product.getQuantity() + "")) {
					validateResult = "产品数量不能为空";
					return validateResult;
				}
				if (product.getSupplyid() < 0) {
					validateResult = "供应商不能为空";
					return validateResult;
				}
				List<Seri> seris = product.getSerials();
				if (seris == null || seris.size() != product.getQuantity()) {
					validateResult = "quantity数量和imei个数不相等";
					return validateResult;
				} else {
					for (Seri seri : seris) {
						if (StringUtils.isBlank(seri.getImei())) {
							validateResult = "Imei不能为空";
							return validateResult;
						}
					}
				}
			}
		}
		return validateResult;
	}

	public static void main(String[] args) {
		String xml = "<allotinback><allotcode>12345678</allotcode><intocode>圆通</intocode>"
				+ "<products><product><supplyid>1</supplyid><productcode>item1</productcode><quantity>2</quantity><serials><seri><imei>1"
				+ "</imei></seri><seri><imei>2</imei> </seri> </serials>  <A></A></product></products></allotinback>";
		AllotInBillBackService a = new AllotInBillBackService();
		try {
			AllotOutBillFromXml allotOutBill = (AllotOutBillFromXml) VOXMLMapping
					.fromXML(xml, AllotOutBillFromXml.class, null);// 反射xml-->实体类
			System.out.println(a.validateXml(allotOutBill));
		} catch (Exception e) {
			System.out.println("解析失败");
		}
	}
}
